package com.sh.data.engine.domain.util;

import gudusoft.gsqlparser.EDbVendor;
import gudusoft.gsqlparser.nodes.TTable;
import gudusoft.gsqlparser.sqlenv.ESQLDataObjectType;
import gudusoft.gsqlparser.sqlenv.TSQLEnv;

import java.io.*;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

public class SQLUtil {
    public static boolean isEmpty(String value) {
        return (value == null || value.trim().length() == 0);
    }

    public static String getFileContent(File file) {
        String charset = null;
        String sqlfilename = file.getAbsolutePath();
        int read = 0;
        try {
            FileInputStream fr = new FileInputStream(sqlfilename);
            byte[] bom = new byte[4];
            fr.read(bom, 0, bom.length);
            if (bom[0] == 0 && bom[1] == 0 && bom[2] == -2 && bom[3] == -1) {
                charset = "UTF-32BE";
                read = 4;
            } else if (bom[0] == -1 && bom[1] == -2 && bom[2] == 0 && bom[3] == 0) {
                charset = "UTF-32LE";
                read = 4;
            } else if (bom[0] == -17 && bom[1] == -69 && bom[2] == -65) {
                charset = "UTF-8";
                read = 3;
            } else if (bom[0] == -2 && bom[1] == -1) {
                charset = "UTF-16BE";
                read = 2;
            } else if (bom[0] == -1 && bom[1] == -2) {
                charset = "UTF-16LE";
                read = 2;
            } else {
                charset = "UTF-8";
                read = 0;
            }
            fr.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        Long filelength = Long.valueOf(file.length());
        byte[] filecontent = new byte[filelength.intValue()];
        try {
            InputStream in = new BufferedInputStream(new FileInputStream(sqlfilename));
            in.read(filecontent);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        byte[] content = new byte[filelength.intValue() - read];
        System.arraycopy(filecontent, read, content, 0, content.length);
        try {
            String fileContent = (new String(content, (charset == null) ? Charset.defaultCharset().name() : charset)).trim();
            return fileContent.replace(",", "");
        } catch (UnsupportedEncodingException e) {
            System.err
                .println(("The OS does not support " + charset == null) ? Charset.defaultCharset().name() : charset);
            return null;
        }
    }

    public static String getInputStreamContent(InputStream is, boolean close) {
        try {
            ByteArrayOutputStream out = new ByteArrayOutputStream(4096);
            byte[] tmp = new byte[4096];
            while (true) {
                int r = is.read(tmp);
                if (r == -1)
                    break;
                out.write(tmp, 0, r);
            }
            byte[] bytes = out.toByteArray();
            if (close)
                is.close();
            out.close();
            String content = new String(bytes);
            return content.trim();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static String getFileContent(String filePath) {
        if (filePath == null)
            return "";
        File file = new File(filePath);
        if (!file.exists() || file.isDirectory())
            return "";
        return getFileContent(file);
    }

    public static String trimColumnStringQuote(String string) {
        try {
            if (string == null)
                return string;
            if (string.indexOf('.') != -1) {
                List<String> splits = parseNames(string);
                if (splits.size() > 1) {
                    StringBuilder buffer = new StringBuilder();
                    for (int i = 0; i < splits.size(); i++) {
                        String segment = splits.get(i);
                        if (parseNames(trimColumnStringQuote(segment)).size() > 1) {
                            buffer.append(segment);
                        } else {
                            buffer.append(trimColumnStringQuote(segment));
                        }
                        if (i < splits.size() - 1)
                            buffer.append(".");
                    }
                    string = buffer.toString();
                    return string;
                }
            }
            if (string.length() < 2)
                return string;
            if (string.startsWith("'") && string.endsWith("'"))
                return string.substring(1, string.length() - 1);
            if (string.startsWith("\"") && string.endsWith("\""))
                return string.substring(1, string.length() - 1);
            if (string.startsWith("`") && string.endsWith("`"))
                return string.substring(1, string.length() - 1);
            if (string.startsWith("[") && string.endsWith("]"))
                return string.substring(1, string.length() - 1);
            return string;
        } catch (Exception e) {
            return string;
        }
    }

    public static void main(String[] args) {
        System.out.println(parseNames("`project-dev.ZZZ.LMAP`", EDbVendor.dbvmysql));
    }

    public static List<String> parseNames(String nameString) {
        return parseNames(nameString, null);
    }

    public static List<String> parseNames(String nameString, EDbVendor vendor) {
        if (nameString == null)
            return Collections.EMPTY_LIST;
        String name = nameString.trim();
        List<String> names = new ArrayList<>();
        if (vendor == EDbVendor.dbvbigquery &&
            name.contains("`")) {
            names.addAll(Arrays.asList(name.replace("`", "").split("\\s*\\.\\s*")));
            return names;
        }
        try {
            String[] splits = nameString.split("\\s*\\.\\s*");
            if (name.contains("'")) {
                for (int i = 0; i < splits.length; i++) {
                    String split = splits[i].trim();
                    if (split.startsWith("'") && !split.endsWith("'")) {
                        StringBuilder buffer = new StringBuilder();
                        buffer.append(splits[i]);
                        while (!(split = splits[++i].trim()).endsWith("'")) {
                            buffer.append(".");
                            buffer.append(splits[i]);
                            if (i == splits.length - 1)
                                break;
                        }
                        buffer.append(".");
                        buffer.append(splits[i]);
                        names.add(buffer.toString());
                    } else {
                        names.add(splits[i]);
                    }
                }
            } else if (name.contains("`")) {
                for (int i = 0; i < splits.length; i++) {
                    String split = splits[i].trim();
                    if (split.startsWith("`") && !split.endsWith("`")) {
                        StringBuilder buffer = new StringBuilder();
                        buffer.append(splits[i]);
                        while (!(split = splits[++i].trim()).endsWith("`")) {
                            buffer.append(".");
                            buffer.append(splits[i]);
                            if (i == splits.length - 1)
                                break;
                        }
                        buffer.append(".");
                        buffer.append(splits[i]);
                        names.add(buffer.toString());
                    } else {
                        names.add(splits[i]);
                    }
                }
            } else if (name.contains("\"")) {
                for (int i = 0; i < splits.length; i++) {
                    String split = splits[i].trim();
                    if (split.startsWith("\"") && !split.endsWith("\"")) {
                        StringBuilder buffer = new StringBuilder();
                        buffer.append(splits[i]);
                        while (!(split = splits[++i].trim()).endsWith("\"")) {
                            buffer.append(".");
                            buffer.append(splits[i]);
                            if (i == splits.length - 1)
                                break;
                        }
                        buffer.append(".");
                        buffer.append(splits[i]);
                        names.add(buffer.toString());
                    } else {
                        names.add(splits[i]);
                    }
                }
            } else if (name.contains("[") && name.contains("]")) {
                for (int i = 0; i < splits.length; i++) {
                    String split = splits[i].trim();
                    if (split.startsWith("[") && !split.endsWith("]")) {
                        StringBuilder buffer = new StringBuilder();
                        buffer.append(splits[i]);
                        if (i < splits.length - 1)
                            while (!(split = splits[++i].trim()).endsWith("]")) {
                                buffer.append(".");
                                buffer.append(splits[i]);
                                if (i == splits.length - 1)
                                    break;
                            }
                        buffer.append(".");
                        buffer.append(splits[i]);
                        names.add(buffer.toString());
                    } else {
                        names.add(splits[i]);
                    }
                }
            } else {
                names.addAll(Arrays.asList(splits));
            }
        } catch (Throwable e) {
            names.clear();
            names.add(nameString);
        }
        return names;
    }

    public static void writeToFile(File file, InputStream source, boolean close) {
        BufferedInputStream bis = null;
        BufferedOutputStream fouts = null;
        try {
            bis = new BufferedInputStream(source);
            if (!file.exists()) {
                if (!file.getParentFile().exists())
                    file.getParentFile().mkdirs();
                file.createNewFile();
            }
            fouts = new BufferedOutputStream(new FileOutputStream(file));
            byte[] b = new byte[1024];
            int i = 0;
            while ((i = bis.read(b)) != -1)
                fouts.write(b, 0, i);
            fouts.flush();
            fouts.close();
            if (close)
                bis.close();
        } catch (IOException e) {
            Logger.getLogger(SQLUtil.class.getName()).log(Level.WARNING, "Write file failed.", e);
            try {
                if (fouts != null)
                    fouts.close();
            } catch (IOException f) {
                Logger.getLogger(SQLUtil.class.getName()).log(Level.WARNING, "Close output stream failed.", f);
            }
            if (close)
                try {
                    if (bis != null)
                        bis.close();
                } catch (IOException f) {
                    Logger.getLogger(SQLUtil.class.getName()).log(Level.WARNING, "Close input stream failed.", f);
                }
        }
    }

    public static void writeToFile(File file, String string) throws IOException {
        if (!file.exists()) {
            if (!file.getParentFile().exists())
                file.getParentFile().mkdirs();
            file.createNewFile();
        }
        PrintWriter out = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file)));
        if (string != null)
            out.print(string);
        out.close();
    }

    public static void appendToFile(File file, String string) throws IOException {
        if (!file.exists()) {
            if (!file.getParentFile().exists())
                file.getParentFile().mkdirs();
            file.createNewFile();
        }
        PrintWriter out = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file, true)));
        if (string != null)
            out.println(string);
        out.close();
    }

    public static void deltree(File root) {
        if (root == null || !root.exists())
            return;
        if (root.isFile()) {
            root.delete();
            return;
        }
        File[] children = root.listFiles();
        if (children != null)
            for (int i = 0; i < children.length; i++)
                deltree(children[i]);
        root.delete();
    }

    public static InputStream getInputStreamWithoutBom(String file) throws IOException {
        UnicodeInputStream stream = null;
        FileInputStream fis = new FileInputStream(file);
        stream = new UnicodeInputStream(fis, null);
        return stream;
    }

    public static class UnicodeInputStream extends InputStream {
        PushbackInputStream internalIn;

        boolean isInited = false;

        String defaultEnc;

        String encoding;

        private static final int BOM_SIZE = 4;

        public UnicodeInputStream(InputStream in, String defaultEnc) {
            this.internalIn = new PushbackInputStream(in, 4);
            this.defaultEnc = defaultEnc;
        }

        public String getDefaultEncoding() {
            return this.defaultEnc;
        }

        public String getEncoding() {
            if (!this.isInited)
                try {
                    init();
                } catch (IOException ex) {
                    IllegalStateException ise = new IllegalStateException("Init method failed.");
                    ise.initCause(ise);
                    throw ise;
                }
            return this.encoding;
        }

        protected void init() throws IOException {
            int unread;
            if (this.isInited)
                return;
            byte[] bom = new byte[4];
            int n = this.internalIn.read(bom, 0, bom.length);
            if (bom[0] == 0 && bom[1] == 0 && bom[2] == -2 && bom[3] == -1) {
                this.encoding = "UTF-32BE";
                unread = n - 4;
            } else if (bom[0] == -1 && bom[1] == -2 && bom[2] == 0 && bom[3] == 0) {
                this.encoding = "UTF-32LE";
                unread = n - 4;
            } else if (bom[0] == -17 && bom[1] == -69 && bom[2] == -65) {
                this.encoding = "UTF-8";
                unread = n - 3;
            } else if (bom[0] == -2 && bom[1] == -1) {
                this.encoding = "UTF-16BE";
                unread = n - 2;
            } else if (bom[0] == -1 && bom[1] == -2) {
                this.encoding = "UTF-16LE";
                unread = n - 2;
            } else {
                this.encoding = this.defaultEnc;
                unread = n;
            }
            if (unread > 0)
                this.internalIn.unread(bom, n - unread, unread);
            this.isInited = true;
        }

        public void close() throws IOException {
            this.internalIn.close();
        }

        public int read() throws IOException {
            return this.internalIn.read();
        }
    }

    public static boolean compareIdentifier(EDbVendor dbVendor, ESQLDataObjectType sqlDataObjectType, String identifier1, String identifier2) {
        List<String> segments1 = parseNames(identifier1);
        List<String> segments2 = parseNames(identifier2);
        if (segments1.size() != segments2.size())
            return false;
        boolean supportCatalog = TSQLEnv.supportCatalog(dbVendor);
        boolean supportSchema = TSQLEnv.supportSchema(dbVendor);
        if (supportCatalog && supportSchema) {
            if (sqlDataObjectType == ESQLDataObjectType.dotColumn) {
                if (segments1.size() > 4)
                    return (TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotCatalog, segments1.get(0), segments2
                        .get(0)) &&
                        TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotSchema, segments1.get(1), segments2
                            .get(1)) &&
                        TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotTable, segments1.get(2), segments2
                            .get(2)) &&
                        TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotColumn, mergeSegments(segments1, 3),
                            mergeSegments(segments2, 3)));
                if (segments1.size() == 4)
                    return (TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotCatalog, segments1.get(0), segments2
                        .get(0)) &&
                        TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotSchema, segments1.get(1), segments2
                            .get(1)) &&
                        TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotTable, segments1.get(2), segments2
                            .get(2)) &&
                        TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotColumn, segments1.get(3), segments2
                            .get(3)));
                if (segments1.size() == 3)
                    return (TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotSchema, segments1.get(0), segments2
                        .get(0)) &&
                        TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotTable, segments1.get(1), segments2
                            .get(1)) &&
                        TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotColumn, segments1.get(2), segments2
                            .get(2)));
                if (segments1.size() == 2)
                    return (TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotTable, segments1.get(0), segments2
                        .get(0)) &&
                        TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotColumn, segments1.get(1), segments2
                            .get(1)));
                if (segments1.size() == 1)
                    return TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotColumn, segments1.get(0), segments2
                        .get(0));
            } else if (sqlDataObjectType == ESQLDataObjectType.dotTable || sqlDataObjectType == ESQLDataObjectType.dotOraclePackage || sqlDataObjectType == ESQLDataObjectType.dotFunction || sqlDataObjectType == ESQLDataObjectType.dotProcedure || sqlDataObjectType == ESQLDataObjectType.dotTrigger) {
                if (segments1.size() > 3)
                    return (TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotCatalog, segments1.get(0), segments2
                        .get(0)) &&
                        TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotSchema, segments1.get(1), segments2
                            .get(1)) &&
                        TSQLEnv.compareIdentifier(dbVendor, sqlDataObjectType, mergeSegments(segments1, 2), mergeSegments(segments2, 2)));
                if (segments1.size() == 3)
                    return (TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotCatalog, segments1.get(0), segments2
                        .get(0)) &&
                        TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotSchema, segments1.get(1), segments2
                            .get(1)) &&
                        TSQLEnv.compareIdentifier(dbVendor, sqlDataObjectType, segments1.get(2), segments2.get(2)));
                if (segments1.size() == 2)
                    return (TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotSchema, segments1.get(0), segments2
                        .get(0)) &&
                        TSQLEnv.compareIdentifier(dbVendor, sqlDataObjectType, segments1.get(1), segments2.get(1)));
                if (segments1.size() == 1)
                    return TSQLEnv.compareIdentifier(dbVendor, sqlDataObjectType, segments1.get(0), segments2.get(0));
            } else if (sqlDataObjectType == ESQLDataObjectType.dotSchema) {
                if (segments1.size() > 2)
                    return (TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotCatalog, segments1.get(0), segments2
                        .get(0)) &&
                        TSQLEnv.compareIdentifier(dbVendor, sqlDataObjectType, mergeSegments(segments1, 1), mergeSegments(segments2, 1)));
                if (segments1.size() == 2)
                    return (TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotCatalog, segments1.get(0), segments2
                        .get(0)) &&
                        TSQLEnv.compareIdentifier(dbVendor, sqlDataObjectType, segments1.get(1), segments2.get(1)));
                if (segments1.size() == 1)
                    return TSQLEnv.compareIdentifier(dbVendor, sqlDataObjectType, segments1.get(0), segments2.get(0));
            } else if (sqlDataObjectType == ESQLDataObjectType.dotCatalog) {
                if (segments1.size() > 1)
                    return TSQLEnv.compareIdentifier(dbVendor, sqlDataObjectType, mergeSegments(segments1, 0), mergeSegments(segments2, 0));
                if (segments1.size() == 1)
                    return TSQLEnv.compareIdentifier(dbVendor, sqlDataObjectType, segments1.get(0), segments2.get(0));
            }
        } else if (supportCatalog) {
            if (sqlDataObjectType == ESQLDataObjectType.dotColumn) {
                if (segments1.size() > 3)
                    return (TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotCatalog, segments1.get(0), segments2
                        .get(0)) &&
                        TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotTable, segments1.get(1), segments2
                            .get(1)) &&
                        TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotColumn, mergeSegments(segments1, 2),
                            mergeSegments(segments2, 2)));
                if (segments1.size() == 3)
                    return (TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotCatalog, segments1.get(0), segments2
                        .get(0)) &&
                        TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotTable, segments1.get(1), segments2
                            .get(1)) &&
                        TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotColumn, segments1.get(2), segments2
                            .get(2)));
                if (segments1.size() == 2)
                    return (TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotTable, segments1.get(0), segments2
                        .get(0)) &&
                        TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotColumn, segments1.get(1), segments2
                            .get(1)));
                if (segments1.size() == 1)
                    return TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotColumn, segments1.get(0), segments2
                        .get(0));
            } else if (sqlDataObjectType == ESQLDataObjectType.dotTable || sqlDataObjectType == ESQLDataObjectType.dotOraclePackage || sqlDataObjectType == ESQLDataObjectType.dotFunction || sqlDataObjectType == ESQLDataObjectType.dotProcedure || sqlDataObjectType == ESQLDataObjectType.dotTrigger) {
                if (segments1.size() > 2)
                    return (TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotCatalog, segments1.get(0), segments2
                        .get(0)) &&
                        TSQLEnv.compareIdentifier(dbVendor, sqlDataObjectType, mergeSegments(segments1, 1), mergeSegments(segments2, 1)));
                if (segments1.size() == 2)
                    return (TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotCatalog, segments1.get(0), segments2
                        .get(0)) &&
                        TSQLEnv.compareIdentifier(dbVendor, sqlDataObjectType, segments1.get(1), segments2.get(1)));
                if (segments1.size() == 1)
                    return TSQLEnv.compareIdentifier(dbVendor, sqlDataObjectType, segments1.get(0), segments2.get(0));
            } else if (sqlDataObjectType == ESQLDataObjectType.dotCatalog || sqlDataObjectType == ESQLDataObjectType.dotSchema) {
                if (segments1.size() > 1)
                    return TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotCatalog, mergeSegments(segments1, 0), mergeSegments(segments2, 0));
                if (segments1.size() == 1)
                    return TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotCatalog, segments1.get(0), segments2.get(0));
            }
        } else if (supportSchema) {
            if (sqlDataObjectType == ESQLDataObjectType.dotColumn) {
                if (segments1.size() > 3)
                    return (TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotSchema, segments1.get(0), segments2
                        .get(0)) &&
                        TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotTable, segments1.get(1), segments2
                            .get(1)) &&
                        TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotColumn, mergeSegments(segments1, 2),
                            mergeSegments(segments2, 2)));
                if (segments1.size() == 3)
                    return (TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotSchema, segments1.get(0), segments2
                        .get(0)) &&
                        TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotTable, segments1.get(1), segments2
                            .get(1)) &&
                        TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotColumn, segments1.get(2), segments2
                            .get(2)));
                if (segments1.size() == 2)
                    return (TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotTable, segments1.get(0), segments2
                        .get(0)) &&
                        TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotColumn, segments1.get(1), segments2
                            .get(1)));
                if (segments1.size() == 1)
                    return TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotColumn, segments1.get(0), segments2
                        .get(0));
            } else if (sqlDataObjectType == ESQLDataObjectType.dotTable || sqlDataObjectType == ESQLDataObjectType.dotOraclePackage || sqlDataObjectType == ESQLDataObjectType.dotFunction || sqlDataObjectType == ESQLDataObjectType.dotProcedure || sqlDataObjectType == ESQLDataObjectType.dotTrigger) {
                if (segments1.size() > 2)
                    return (TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotSchema, segments1.get(0), segments2
                        .get(0)) &&
                        TSQLEnv.compareIdentifier(dbVendor, sqlDataObjectType, mergeSegments(segments1, 1), mergeSegments(segments2, 1)));
                if (segments1.size() == 2)
                    return (TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotSchema, segments1.get(0), segments2
                        .get(0)) &&
                        TSQLEnv.compareIdentifier(dbVendor, sqlDataObjectType, segments1.get(1), segments2.get(1)));
                if (segments1.size() == 1)
                    return TSQLEnv.compareIdentifier(dbVendor, sqlDataObjectType, segments1.get(0), segments2.get(0));
            } else if (sqlDataObjectType == ESQLDataObjectType.dotCatalog || sqlDataObjectType == ESQLDataObjectType.dotSchema) {
                if (segments1.size() > 1)
                    return TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotSchema, mergeSegments(segments1, 0), mergeSegments(segments2, 0));
                if (segments1.size() == 1)
                    return TSQLEnv.compareIdentifier(dbVendor, ESQLDataObjectType.dotSchema, segments1.get(0), segments2.get(0));
            }
        }
        return false;
    }

    public static String normalizeIdentifier(EDbVendor dbVendor, ESQLDataObjectType objectType, String identifier) {
        if (identifier == null)
            return null;
        String originIdentifier = identifier;
        identifier = TSQLEnv.normalizeIdentifier(dbVendor, objectType, identifier);
        boolean collationSensitive = false;
//    switch (objectType) {
//      case dbvmssql:
//        collationSensitive = TSQLEnv.catalogCollationCaseSensitive[dbVendor.ordinal()];
//        break;
//        collationSensitive = TSQLEnv.defaultCollationCaseSensitive[dbVendor.ordinal()];
//        break;
//    }
        collationSensitive = true;
        if (parseNames(identifier).size() > 1)
            return collationSensitive ? originIdentifier : originIdentifier.toUpperCase();
        return collationSensitive ? identifier : identifier.toUpperCase();
    }

    public static String getIdentifierNormalColumnName(EDbVendor dbVendor, String name) {
        return getIdentifierNormalName(dbVendor, name, ESQLDataObjectType.dotColumn);
    }

    public static String getIdentifierNormalTableName(EDbVendor dbVendor, String name) {
        return getIdentifierNormalName(dbVendor, name, ESQLDataObjectType.dotTable);
    }

    public static String getTableFullName(EDbVendor vendor, String database, String schema, String table) {
        boolean supportCatalog = TSQLEnv.supportCatalog(vendor);
        boolean supportSchema = TSQLEnv.supportSchema(vendor);
        StringBuilder builder = new StringBuilder();
        if (supportCatalog && supportSchema) {
            if (database != null && !"DEFAULT".equalsIgnoreCase(database))
                builder.append(database).append(".");
            if (schema != null && !"DEFAULT".equalsIgnoreCase(schema)) {
                builder.append(schema).append(".");
            } else if (builder.length() > 0) {
                builder.append("DEFAULT").append(".");
            }
            builder.append(table);
        } else if (supportCatalog) {
            if (database != null && !"DEFAULT".equalsIgnoreCase(database))
                builder.append(database).append(".");
            builder.append(table);
        } else if (supportSchema) {
            if (schema != null && !"DEFAULT".equalsIgnoreCase(schema))
                builder.append(schema).append(".");
            builder.append(table);
        }
        return builder.toString();
    }

    public static String getIdentifierNormalName(EDbVendor dbVendor, String name, ESQLDataObjectType sqlDataObjectType) {
        if (name == null)
            return null;
        List<String> segments = parseNames(name);
        StringBuilder builder = new StringBuilder();
        boolean supportCatalog = TSQLEnv.supportCatalog(dbVendor);
        boolean supportSchema = TSQLEnv.supportSchema(dbVendor);
        if (supportCatalog && supportSchema) {
            if (sqlDataObjectType == ESQLDataObjectType.dotColumn) {
                if (segments.size() > 4) {
                    builder.append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotCatalog, segments.get(0)))
                        .append(".")
                        .append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotSchema, segments.get(1)))
                        .append(".")
                        .append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotTable, segments.get(2)))
                        .append(".")
                        .append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotColumn, mergeSegments(segments, 3)));
                } else if (segments.size() == 4) {
                    builder.append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotCatalog, segments.get(0)))
                        .append(".")
                        .append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotSchema, segments.get(1)))
                        .append(".")
                        .append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotTable, segments.get(2)))
                        .append(".")
                        .append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotColumn, segments.get(3)));
                } else if (segments.size() == 3) {
                    builder.append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotSchema, segments.get(0)))
                        .append(".")
                        .append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotTable, segments.get(1)))
                        .append(".")
                        .append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotColumn, segments.get(2)));
                } else if (segments.size() == 2) {
                    builder.append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotTable, segments.get(0)))
                        .append(".")
                        .append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotColumn, segments.get(1)));
                } else if (segments.size() == 1) {
                    builder.append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotColumn, segments.get(0)));
                }
            } else if (sqlDataObjectType == ESQLDataObjectType.dotTable || sqlDataObjectType == ESQLDataObjectType.dotOraclePackage || sqlDataObjectType == ESQLDataObjectType.dotFunction || sqlDataObjectType == ESQLDataObjectType.dotProcedure || sqlDataObjectType == ESQLDataObjectType.dotTrigger) {
                if (segments.size() > 3) {
                    builder.append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotCatalog, segments.get(0)))
                        .append(".")
                        .append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotSchema, segments.get(1)))
                        .append(".").append(normalizeIdentifier(dbVendor, sqlDataObjectType, mergeSegments(segments, 2)));
                } else if (segments.size() == 3) {
                    builder.append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotCatalog, segments.get(0)))
                        .append(".")
                        .append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotSchema, segments.get(1)))
                        .append(".").append(normalizeIdentifier(dbVendor, sqlDataObjectType, segments.get(2)));
                } else if (segments.size() == 2) {
                    builder.append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotSchema, segments.get(0)))
                        .append(".").append(normalizeIdentifier(dbVendor, sqlDataObjectType, segments.get(1)));
                } else if (segments.size() == 1) {
                    builder.append(normalizeIdentifier(dbVendor, sqlDataObjectType, segments.get(0)));
                }
            } else if (sqlDataObjectType == ESQLDataObjectType.dotSchema) {
                if (segments.size() > 2) {
                    builder.append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotCatalog, segments.get(0)))
                        .append(".").append(normalizeIdentifier(dbVendor, sqlDataObjectType, mergeSegments(segments, 1)));
                } else if (segments.size() == 2) {
                    builder.append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotCatalog, segments.get(0)))
                        .append(".").append(normalizeIdentifier(dbVendor, sqlDataObjectType, segments.get(1)));
                } else if (segments.size() == 1) {
                    builder.append(normalizeIdentifier(dbVendor, sqlDataObjectType, segments.get(0)));
                }
            } else if (sqlDataObjectType == ESQLDataObjectType.dotCatalog) {
                if (segments.size() > 1) {
                    builder.append(normalizeIdentifier(dbVendor, sqlDataObjectType, mergeSegments(segments, 0)));
                } else if (segments.size() == 1) {
                    builder.append(normalizeIdentifier(dbVendor, sqlDataObjectType, segments.get(0)));
                }
            }
        } else if (supportCatalog) {
            if (sqlDataObjectType == ESQLDataObjectType.dotColumn) {
                if (segments.size() > 3) {
                    builder.append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotCatalog, segments.get(0)))
                        .append(".")
                        .append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotTable, segments.get(1)))
                        .append(".")
                        .append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotColumn, mergeSegments(segments, 2)));
                } else if (segments.size() == 3) {
                    builder.append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotCatalog, segments.get(0)))
                        .append(".")
                        .append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotTable, segments.get(1)))
                        .append(".")
                        .append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotColumn, segments.get(2)));
                } else if (segments.size() == 2) {
                    builder.append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotTable, segments.get(0)))
                        .append(".")
                        .append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotColumn, segments.get(1)));
                } else if (segments.size() == 1) {
                    builder.append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotColumn, segments.get(0)));
                }
            } else if (sqlDataObjectType == ESQLDataObjectType.dotTable || sqlDataObjectType == ESQLDataObjectType.dotOraclePackage || sqlDataObjectType == ESQLDataObjectType.dotFunction || sqlDataObjectType == ESQLDataObjectType.dotProcedure || sqlDataObjectType == ESQLDataObjectType.dotTrigger) {
                if (segments.size() > 2) {
                    builder.append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotCatalog, segments.get(0)))
                        .append(".").append(normalizeIdentifier(dbVendor, sqlDataObjectType, mergeSegments(segments, 1)));
                } else if (segments.size() == 2) {
                    builder.append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotCatalog, segments.get(0)))
                        .append(".").append(normalizeIdentifier(dbVendor, sqlDataObjectType, segments.get(1)));
                } else if (segments.size() == 1) {
                    builder.append(normalizeIdentifier(dbVendor, sqlDataObjectType, segments.get(0)));
                }
            } else if (sqlDataObjectType == ESQLDataObjectType.dotSchema || sqlDataObjectType == ESQLDataObjectType.dotCatalog) {
                if (segments.size() > 1) {
                    builder.append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotCatalog, mergeSegments(segments, 0)));
                } else if (segments.size() == 1) {
                    builder.append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotCatalog, segments.get(0)));
                }
            }
        } else if (supportSchema) {
            if (sqlDataObjectType == ESQLDataObjectType.dotColumn) {
                if (segments.size() > 3) {
                    builder.append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotSchema, segments.get(0)))
                        .append(".")
                        .append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotTable, segments.get(1)))
                        .append(".")
                        .append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotColumn, mergeSegments(segments, 2)));
                } else if (segments.size() == 3) {
                    builder.append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotSchema, segments.get(0)))
                        .append(".")
                        .append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotTable, segments.get(1)))
                        .append(".")
                        .append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotColumn, segments.get(2)));
                } else if (segments.size() == 2) {
                    builder.append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotTable, segments.get(0)))
                        .append(".")
                        .append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotColumn, segments.get(1)));
                } else if (segments.size() == 1) {
                    builder.append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotColumn, segments.get(0)));
                }
            } else if (sqlDataObjectType == ESQLDataObjectType.dotTable || sqlDataObjectType == ESQLDataObjectType.dotOraclePackage || sqlDataObjectType == ESQLDataObjectType.dotFunction || sqlDataObjectType == ESQLDataObjectType.dotProcedure || sqlDataObjectType == ESQLDataObjectType.dotTrigger) {
                if (segments.size() > 2) {
                    builder.append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotSchema, segments.get(0)))
                        .append(".").append(normalizeIdentifier(dbVendor, sqlDataObjectType, mergeSegments(segments, 1)));
                } else if (segments.size() == 2) {
                    builder.append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotSchema, segments.get(0)))
                        .append(".").append(normalizeIdentifier(dbVendor, sqlDataObjectType, segments.get(1)));
                } else if (segments.size() == 1) {
                    builder.append(normalizeIdentifier(dbVendor, sqlDataObjectType, segments.get(0)));
                }
            } else if (sqlDataObjectType == ESQLDataObjectType.dotSchema || sqlDataObjectType == ESQLDataObjectType.dotCatalog) {
                if (segments.size() > 1) {
                    builder.append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotSchema, mergeSegments(segments, 0)));
                } else if (segments.size() == 1) {
                    builder.append(normalizeIdentifier(dbVendor, ESQLDataObjectType.dotSchema, segments.get(0)));
                }
            }
        }
        return builder.toString();
    }

    public static String mergeSegments(List<String> segments, int index) {
        StringBuilder buffer = new StringBuilder();
        for (int i = index; i < segments.size(); i++) {
            buffer.append(segments.get(i));
            if (i < segments.size() - 1)
                buffer.append(".");
        }
        return buffer.toString();
    }

    public static boolean isTempTable(String tableName) {
        List<String> segments = parseNames(tableName);
        if (tableName.startsWith("@") || ((String) segments.get(segments.size() - 1)).startsWith("@"))
            return true;
        if (tableName.startsWith("#") || ((String) segments.get(segments.size() - 1)).startsWith("#"))
            return true;
        return false;
    }

    public static boolean isTempTable(TTable table, EDbVendor vendor) {
        switch (vendor) {
            case dbvmssql:
                return table.getName().startsWith("#");
        }
        return false;
    }

    public static File[] listFiles(File sqlFiles) {
        List<File> children = new ArrayList<>();
        if (sqlFiles != null)
            listFiles(sqlFiles, children);
        return children.<File>toArray(new File[0]);
    }

    public static File[] listFiles(File sqlFiles, FileFilter filter) {
        List<File> children = new ArrayList<>();
        if (sqlFiles != null)
            listFiles(sqlFiles, children, filter);
        return children.<File>toArray(new File[0]);
    }

    public static void listFiles(File rootFile, List<File> children) {
        if (rootFile.isFile()) {
            children.add(rootFile);
        } else {
            File[] files = rootFile.listFiles();
            if (files != null)
                for (int i = 0; i < files.length; i++)
                    listFiles(files[i], children);
        }
    }

    public static void listFiles(File rootFile, List<File> children, FileFilter filter) {
        if (rootFile.isFile() && filter.accept(rootFile)) {
            children.add(rootFile);
        } else {
            File[] files = rootFile.listFiles(filter);
            if (files != null)
                for (int i = 0; i < files.length; i++)
                    listFiles(files[i], children, filter);
        }
    }

    public static String readFile(File file) {
        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader(file));
            String line = null;
            String ls = System.getProperty("line.separator");
            while ((line = reader.readLine()) != null) {
                stringBuilder.append(line);
                stringBuilder.append(ls);
            }
            stringBuilder.deleteCharAt(stringBuilder.length() - 1);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null)
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }
        return stringBuilder.toString();
    }

    public static String stringToMD5(String plainText) {
        byte[] secretBytes = null;
        try {
            secretBytes = MessageDigest.getInstance("md5").digest(plainText.getBytes("UTF-8"));
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < secretBytes.length; i++)
                sb.append(Integer.toHexString(secretBytes[i] & 0xFF | 0x100).substring(1, 3));
            return sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

